package com.indusfo.spc.untlis;

import com.indusfo.spc.config.PieceFlowConfig;
import com.indusfo.spc.exception.GlobalException;

import com.indusfo.spc.exception.UploadErrorException;
import com.indusfo.spc.vo.JSONObject;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;


/**
 * @author louk
 * @date 2019/10/21 8:35
 * @description 文件下载
 */
public class FileUtil {
    public static void download(String filename, HttpServletResponse res, HttpServletRequest request) throws IOException {

        try {

            String realFileName = getFileName(filename);
            Resource resource = new ClassPathResource("excelModel/"+realFileName+".xlsx");
            if(filename.equals("22")){
                resource = new ClassPathResource("excelModel/"+realFileName+".zip");
            }
            File file = resource.getFile();
            String fileName = resource.getFilename();
            InputStream inputStream = new FileInputStream(file);
            // 设置信息给客户端不解析
            String type = new MimetypesFileTypeMap().getContentType(filename);
            // 设置contenttype，即告诉客户端所发送的数据属于什么类型
            res.setHeader("Content-type",type);
            //强制下载不打开
            res.setContentType("application/force-download");
            //解决火狐浏览器文件名中文乱码问题
            String agent = request.getHeader("User-Agent");
            //根据不同浏览器进行不同的编码
            String realFilename = "";
            if (agent.contains("MSIE")) {
                // IE浏览器
                realFilename = URLEncoder.encode(fileName, "utf-8");
                realFilename = realFilename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器，此处使用java8
                realFilename = "=?utf-8?B?" + Base64.getEncoder().encodeToString(fileName.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                realFilename = URLEncoder.encode(fileName, "utf-8");
            }
            OutputStream out = res.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            res.setHeader("Content-Disposition", "attachment; filename="+realFilename);

            int b = 0;
            byte[] buffer = new byte[1000000];
            while (b != -1) {
                b = inputStream.read(buffer);
                if(b!=-1) {
                    out.write(buffer, 0, b);
                }
            }
            inputStream.close();
            out.close();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void downloadExcel(String filename, HttpServletResponse res, HttpServletRequest request) throws IOException {
        String target = PieceFlowConfig.getProfile();
        File file = new File(target+filename);
        try {

            String fileName=file.getName();
            InputStream inputStream = new FileInputStream(file);
            // 设置信息给客户端不解析
            String type = new MimetypesFileTypeMap().getContentType(fileName);
            // 设置contenttype，即告诉客户端所发送的数据属于什么类型
            res.setHeader("Content-type",type);
            //强制下载不打开
            res.setContentType("application/force-download");
            //解决火狐浏览器文件名中文乱码问题
            String agent = request.getHeader("User-Agent");
            //根据不同浏览器进行不同的编码
            String realFilename = "";
            if (agent.contains("MSIE")) {
                // IE浏览器
                realFilename = URLEncoder.encode(fileName, "utf-8");
                realFilename = realFilename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器，此处使用java8
                realFilename = "=?utf-8?B?" + Base64.getEncoder().encodeToString(fileName.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                realFilename = URLEncoder.encode(fileName, "utf-8");
            }
            OutputStream out = res.getOutputStream();
            //使用URLEncoder来防止文件名乱码或者读取错误
            res.setHeader("Content-Disposition", "attachment; filename="+realFilename);

            int b = 0;
            byte[] buffer = new byte[1000000];
            while (b != -1) {
                b = inputStream.read(buffer);
                if(b!=-1) {
                    out.write(buffer, 0, b);
                }
            }
            inputStream.close();
            out.close();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            deleteFile(file);
        }
    }
    private static  String getFileName(String filename){
        String fileName="";
        switch (filename){
            case "15":
                fileName="用户模板";
            break;
            case "2":
                fileName="物料信息模板";
                break;
            case "3":
                fileName="车间模板";
                break;
            case "4":
                fileName="产线模板";
                break;
            case "5":
                fileName="工位模板";
                break;
            case "6":
                fileName="工序模板";
                break;
            case "7":
                fileName="采集项目模板";
                break;
            case "8":
                fileName="设备模板";
                break;
            case "9":
                fileName="托盘模板";
                break;
            case "10":
                fileName="班次信息模板";
                break;
            case "11":
                fileName="条码规则模板";
                break;
            case "12":
                fileName="不良原因模板";
                break;
            case "13":
                fileName="不良对策模板";
                break;
            case "22":
                fileName="工艺文件库模板";
                break;
            case "23":
                fileName="仓库模板";
                break;
            case "24":
                fileName="区域模板";
                break;
            case "25":
                fileName="库位模板";
                break;
            case "26":
                fileName="库位下新增物料模板";
                break;
            case "27":
                fileName="任务单分解批次模板";
                break;
            case "28":
                fileName="叫料信息模板";
                break;
            case "29":
                fileName="产品流程模板";
                break;

        }
        return fileName;
    }

    public static void unZip(File srcFile, String destDirPath, String savePath) throws RuntimeException, IOException {
        long startTime = System.currentTimeMillis();

        File file = null;
        file=new File(savePath+srcFile.getName());
//        LogUtils.info("MultipartFile transform to File,MultipartFile name:"+srcFile.getOriginalFilename());
        inputStreamToFile(new FileInputStream(srcFile), file);
        String absolutePath = file.getAbsolutePath();

        if (!file.exists()) {
            throw new RuntimeException(file.getPath() + ",file is not found");
        }
        ZipFile zipFile = null;
        try{
            ZipInputStream zs = new ZipInputStream(new FileInputStream(file), Charset.forName("GBK"));
            BufferedInputStream bs = new BufferedInputStream(zs);
            ZipEntry ze;
            byte[] picture = null;
            while((ze = zs.getNextEntry()) != null){                    //获取zip包中的每一个zip file entry
                String fileName = absolutePath+"/"+ze.getName();                            //pictureName
                picture = new byte[(int) ze.getSize()];                    //读一个文件大小
//                bs.read(picture, 0, (int) ze.getSize());
                File file1 = new File(fileName);
                FileOutputStream outputStream=new FileOutputStream(file1);
                outputStream.write(picture,0,(int) ze.getSize());
            }
            bs.close();
            zs.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
//            LogUtils.info("MultipartFile transform to File completed!");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * @author panchaoyuan
     */
    public static List<File> getAllFiles(String  desFile, List<File> fileList) {
        File file = new File(desFile);
        File[] files = file.listFiles();
        for (File fileIndex : files) {
            if (!fileIndex.exists()) {
                throw new NullPointerException("Cannot find " + fileIndex);
            } else if (fileIndex.isFile()) {
                fileList.add(fileIndex);
            } else {
                if (fileIndex.isDirectory()) {
                    getAllFiles(fileIndex.getAbsolutePath(),fileList);
                }
            }
        }
        return fileList;
    }
    public static  JSONObject fileProcess(File file){
        try {
            // 获取当前时间
            Date date = new Date();
            // 获取文件名
            String content = file.getName();
            // 转换为统一的小写形式
            String fileName = content.toLowerCase();
            // 获取图片的后缀名.doc
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            // 判断是否为word文档,excel文档,pdf文件的类型
            if (!fileName.matches("^.*(doc|docx|xls|xlsx|xl|xla|xlt|xlm|xlc|xlw|pdf|png|jpg|jpeg)$")) {
                // 说明:如果传递的文件不是指定的格式,直接程序结束
                throw new UploadErrorException("上传的文件格式不符合要求");
            }
            // 将文件分年月存储 yyyy/MM/dd
            String datePath = new SimpleDateFormat("yyyy/MM/dd").format(date);
            // 存放的目标目录
            String target = PieceFlowConfig.getProfile();
            // 判断是否有该文件夹:项E/upload/2018/10/09
            String fileDir =  target + datePath;
            File fileFile = new File(fileDir);
            if (!fileFile.exists()) {
                // 没有则创建目录
                fileFile.mkdirs();
            }
            // 生成图片唯一标识码
            String uuid = UuidUtil.getUuid();
            // 拼接文件的名称
            String fileNowName =  uuid + fileType;
            // 实现文件保存:E/upload/yyyy/MM/dd/1231231231231231231.jpg
            String realFilePath = fileDir;
            savePic(new FileInputStream(file),realFilePath,fileNowName);
            // 开启一个线程，去执行word转pdf转png动作,图片格式不需要转换
            if(fileType.matches("^.*(png|jpg|jpeg)$") ){
                realFilePath =  "/upload/"+ datePath + "/" + fileNowName;
            }else{
                OfficeTransformThread officeT = new OfficeTransformThread(realFilePath+"/"+fileNowName);
                new Thread(officeT).start();
                realFilePath =  "/upload/" + datePath + "/" + uuid + ".pdf";
            }
            //设置日期格式
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            Map<String, Object> map = new HashMap<>();
            map.put("content", content);
            map.put("relUrl", realFilePath);
            map.put("uuid", UuidUtil.getUuid());
            map.put("modifyDate", df.format(date));
            // 将路径返回
            // 将路径返回
            return JSONObject.build(JSONObject.SUCCESS,realFilePath);
        } catch (GlobalException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR,e.getMessage());
        } catch (IllegalStateException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR,e.getMessage());
        } catch (IOException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR,e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR,e.getMessage());
        }
    }

    private static  void savePic(InputStream inputStream,String path, String fileName) {

        OutputStream os = null;
        try {
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件

            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void deleteFile(File file){
        //数组指向文件夹中的文件和文件夹
//        File[] fi=file.listFiles();
        //遍历文件和文件夹
            //如果是文件夹，递归查找
            if(file.isDirectory()) {
                File[] fi=file.listFiles();
                for (File newFile : fi) {
                    deleteFile(newFile);
                }
            }else if(file.isFile())
            {
                file.delete();
            }
    }


    public static void main(String args[]) {
        FileUtil.deleteFile(new File("F:\\upload\\Excel导出20200208135754.xlsx"));
    }

    //创建Excel文件
    public static  void createExcel(String path) throws Exception {
        //创建Excel文件对象
        HSSFWorkbook wb = new HSSFWorkbook();
        //用文件对象创建sheet对象  
        HSSFSheet sheet = wb.createSheet("第一个sheet页");
        //用sheet对象创建行对象  
        HSSFRow row = sheet.createRow(0);
        //创建单元格样式     
        CellStyle cellStyle = wb.createCellStyle();
        //用行对象创建单元格对象Cell 
        Cell cell = row.createCell(0);
        //用cell对象读写。设置Excel工作表的值
        cell.setCellValue(1);
        //输出Excel文件
        FileOutputStream output = new FileOutputStream(path);
        wb.write(output);
        output.close();
        output.flush();
    }


}
